package ws

import (
	"context"
	"gim-server/model"
	"gim-server/sdk"
	"time"
)

func SignalingInviteFn(fromUid, toUid string, extData interface{}, pushTitle, pushContent string) (int64, error) {
	var err error
	var timeout int64 = 30
	db := sdk.DB(context.Background())
	msg := &model.TbSignalingInviteMsg{
		FromUID: fromUid,
		ToUID:   toUid,
		Action:  0,
		Expire:  time.Now().Unix() + timeout,
	}
	if err := db.Create(msg).Error; err != nil {
		return 0, err
	}
	time.AfterFunc(time.Second*time.Duration(timeout), func() {
		msg1 := new(model.TbSignalingInviteMsg)
		if err := db.First(msg1, "id = ?", msg.ID).Error; err != nil {
			return
		}
		if msg1.Action == 0 {
			_ = sendMsg(fromUid, &MsgDto{
				Event: SignalingTimeout,
				Data: map[string]interface{}{
					"signaling_id": msg.ID,
				},
			})
			_ = sendMsg(toUid, &MsgDto{
				Event: SignalingTimeout,
				Data: map[string]interface{}{
					"signaling_id": msg.ID,
				},
			})
		}
		db.Delete(msg1)
	})
	if err = sendMsg(toUid, &MsgDto{
		Event: SignalingInvite,
		Data: map[string]interface{}{
			"from_uid":     fromUid,
			"signaling_id": msg.ID,
			"ext_data":     extData,
			"expire":       msg.Expire,
		},
	}); err != nil {
		return 0, err
	}
	TpnsPush(toUid, pushTitle, pushContent, -1, 0)
	return msg.ID, nil
}

func SignalingCancelFn(signalingId int64, pushTitle, pushContent string, extData interface{}) error {
	msg := new(model.TbSignalingInviteMsg)
	db := sdk.DB(context.Background())
	if err := db.First(msg, "id = ?", signalingId).Error; err != nil {
		return err
	}
	_ = sendMsg(msg.ToUID, &MsgDto{
		Event: SignalingCancel,
		Data: map[string]interface{}{
			"signaling_id": signalingId,
			"ext_data":     extData,
		},
	})
	msg.Action = 2
	if err := db.Save(msg).Error; err != nil {
		return err
	}
	TpnsPush(msg.ToUID, pushTitle, pushContent, -1, 0)
	return nil
}

func SignalingAcceptFn(signalingId int64, extData interface{}) error {
	msg := new(model.TbSignalingInviteMsg)
	db := sdk.DB(context.Background())
	if err := db.First(msg, "id = ?", signalingId).Error; err != nil {
		return err
	}
	_ = sendMsg(msg.FromUID, &MsgDto{
		Event: SignalingAccept,
		Data: map[string]interface{}{
			"signaling_id": signalingId,
			"ext_data":     extData,
		},
	})
	msg.Action = 1
	if err := db.Save(msg).Error; err != nil {
		return err
	}
	return nil
}

func SignalingRejectFn(signalingId int64, extData interface{}) error {
	msg := new(model.TbSignalingInviteMsg)
	db := sdk.DB(context.Background())
	if err := db.First(msg, "id = ?", signalingId).Error; err != nil {
		return err
	}
	_ = sendMsg(msg.FromUID, &MsgDto{
		Event: SignalingReject,
		Data: map[string]interface{}{
			"signaling_id": signalingId,
			"ext_data":     extData,
		},
	})
	msg.Action = 3
	if err := db.Save(msg).Error; err != nil {
		return err
	}
	return nil
}

func CheckLastSignaling(uid string) {
	db := sdk.DB(context.Background())
	signalingMsg := new(model.TbSignalingInviteMsg)
	if err := db.First(signalingMsg, "to_uid = ? and expire > ? and action = ?", uid, time.Now().Unix(), 0).Error; err == nil && signalingMsg.FromUID != "" {
		_ = sendMsg(uid, &MsgDto{
			Event: SignalingInvite,
			Data: map[string]interface{}{
				"from_uid":     signalingMsg.FromUID,
				"signaling_id": signalingMsg.ID,
				"expire":       signalingMsg.Expire,
			},
		})
	}
}
